<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2008 by CANTICO ({@link http://www.cantico.fr})
 */
include_once 'base.php';
include_once $GLOBALS['babInstallPath']."utilit/urlincl.php";
require_once dirname(__FILE__) . '/containerwidget.class.php';
require_once dirname(__FILE__) . '/layout.class.php';


/**
 * Constructs a Widget_BusinessApplicationList.
 *
 * @param string		$id			The item unique id.
 * @return Widget_BusinessApplicationList
 */
function Widget_BusinessApplicationList($id = null)
{
	return new Widget_BusinessApplicationList($id);
}











class Widget_BusinessApplicationList extends Widget_ContainerWidget implements Widget_Displayable_Interface {
	

	protected $table_header = array();
	private $current_row;
	protected $nbTotal;
	protected $nbRows;
	protected $nbPages;
	protected $res;
	protected $criterions;
	protected $page_param;
	private $requestparams = null;
	private $baseurl;
	private $canvas = null;
	
	/**
	 * Fetch the first element for each page
	 */
	private $pageinfo = false;
	
	
	public $histogram_max_length = 200;	// px
	

	/**
	 * label used in pages list for previous page
	 */
	protected $previousLabel = '<';
	
	/**
	 * label used in pages list for next page
	 */
	protected $nextLabel = '>';
	
	
	
	
	/**
	 * @param string $id			The item unique id.
	 * @return Widget_Frame
	 */
	public function __construct($id = null)
	{
		parent::__construct($id, Widget_Layout());
		
		// bab_url ne fonctionne pas avec des tableaux avant ovidentia 6.7.91
		// $defaultparams poura etre remplace par array_keys($_GET + $_POST) quand la version minimum sera 6.8.0
		
		$defaultparams = array();
		$arr = $_GET + $_POST;
		foreach($arr as $key => $value) {
			if (is_string($value)) {
				$defaultparams[] = $key;
			}
		}
		
		$this->setRequestParams($defaultparams);
	}


	public function getClasses()
	{
		$classes = parent::getClasses();
		$classes[] = 'widget-businessapplicationlist';
		return $classes;
	}

	
	public function display(Widget_Canvas $canvas)
	{
		return $canvas->BusinessApplicationList($this);
	}
	

	
	
	
	/**
	 * add a column
	 * @param	string			$key		: key used to set values
	 * @param	string			$label		: collum header
	 * @param	string|false	$orderby	: false if column is not orderable
	 * @param	boolean			$html		: encode as html
	 */
	public function addColumn($key, $label, $description = '', $orderby = false, $html = true) {
		$this->table_header[$key] = array(
			'label' 		=> $label,
			'description'	=> $description,
			'orderby' 		=> $orderby,
			'html'			=> $html
		);
	}
	
	/**
	 * add html class to column
	 */
	public function setColumnClassName($key, $classname) {
	
		$this->table_header[$key]['classname'] = $classname;
	}
	
	/**
	 * set background color
	 */
	public function setColumnBgColor($key, $bgcolor) {
		$this->table_header[$key]['bgcolor'] = $bgcolor;
	}
	
	
	/**
	 * Remove html class from column
	 */
	public function removeClassName($key) {
		if (isset($this->table_header[$key]['classname'])) {
			unset($this->table_header[$key]['classname']);
		}
	}
	
	/**
	 * Remove background color from column
	 */
	public function removeBgColor($key) {
		if (isset($this->table_header[$key]['bgcolor'])) {
			unset($this->table_header[$key]['bgcolor']);
		}
	}
	
	
	/**
	 * add html class to all column
	 */
	public function setAllColumnClassName($classname) {
		foreach($this->table_header as $key => $arr) {
			$this->setColumnClassName($key, $classname);
		}
		
		reset($this->table_header);
	}
	
	
	/**
	 * Set background color to all column
	 */
	public function setAllColumnBgColor($bgcolor) {
		foreach($this->table_header as $key => $arr) {
			$this->setColumnBgColor($key, $bgcolor);
			
		}
		
		reset($this->table_header);
	}
	
	
	/**
	 * Remove html class from all column
	 */
	public function removeAllColumnClassName() {
		foreach($this->table_header as $key => $arr) {
			$this->removeClassName($key);
		}
		
		reset($this->table_header);
	}
	
	
	/**
	 * Remove background color from all column
	 */
	public function removeAllColumnBgColor() {
		foreach($this->table_header as $key => $arr) {
			$this->removeBgColor($key);
		}
		
		reset($this->table_header);
	}
	
	

	/**
	 * Display the numeric value as histogram
	 * @param	string	$key		column
	 * @param	float	$max_value	max value contained in column
	 */
	public function setColumnHistogram($key, $max_value) {
		$this->table_header[$key]['histogram'] = (float) $max_value;
	}
	
	
	/**
	 * Set multipage informations
	 * @param	int		$nbTotal		: total rows for list
	 * @param	int		$nbRows 		: rows per pages
	 */
	public function setMultiPage($nbTotal, $nbRows) {
		$this->nbTotal 	= $nbTotal;
		$this->nbRows 	= $nbRows;
		$this->nbPages	= ceil($nbTotal / $nbRows);
	}

	/**
	 * Template method
	 * use { label }, { description }, { orderby }, { classname }
	 */
	final public function getnextheader() {
		if (list($key, $arr) = each($this->table_header)) {

			$this->key = $key;
			$this->label = bab_toHtml($arr['label']);
			$this->description = bab_toHtml($arr['description']);
			$this->orderby = $arr['orderby'] ? bab_toHtml($arr['orderby']) : false;
			$this->classname = isset($arr['classname']) ? $arr['classname'] : false;
			$this->bgcolor = isset($arr['bgcolor']) ? $arr['bgcolor'] : false;
			return true;
		}
		
		reset($this->table_header);
		return false;
	}
	
	/**
	 * 
	 * @return string
	 */
	public function number_format($value) {
		return number_format($value, 1, ',', '');
	}
	
	
	/**
	 * Method to inherit
	 */
	protected function getNextRow() {
		
		// demo for sql ressource
		if (is_resource($this->res)) {
			
			global $babDB;
			if ($arr = $babDB->db_fetch_assoc($this->res)) {
	
				return $arr;
			}
			return false;
		}
	}
	
	
	/**
	 * Template method
	 */
	final public function getnext_tr() {
		
		static $i = 0;
	
		// get row values
		if ($i < $this->nbRows && $this->current_row = $this->getNextRow()) {
			
			$i++;
			return true;
		} 
		$i = 0;
		return false;
	}
	
	/**
	 * Template method
	 * Use { value }
	 */
	final public function getnext_td() {
		if (list($key, $arr) = each($this->table_header)) {
		
			$this->key = $key;

			$this->classname = isset($arr['classname']) ? $arr['classname'] : false;
			$this->bgcolor = isset($arr['bgcolor']) ? $arr['bgcolor'] : false;
			
			
			if ($this->current_row[$key] instanceOf Widget_Item) {
				$this->addItem($this->current_row[$key]);
				$this->value = $this->current_row[$key]->display($this->canvas);
				return true;
			}
		
			if ($arr['html']) {
				$this->value = bab_toHtml($this->current_row[$key], BAB_HTML_ALL & ~BAB_HTML_P);
			} else {
				$this->value = $this->current_row[$key];
			}
			
			
			
			if (isset($arr['histogram'])) {
				$this->value = $this->build_histogram((float) $this->current_row[$key], $arr['histogram']);
			}
		
			return true;
		}
		
		reset($this->table_header);
		return false;
	}
	
	
	/**
	 * Template method
	 * Use { pos }, { page }
	 */
	final public function getnextpage() {
		static $p = 0;
		
		if ($p < $this->nbPages) {
		
			$this->pos = $p * $this->nbRows;
			$this->page_url = bab_url::mod($this->baseurl, $this->getPosParam(), $this->pos);
			$this->page = $p + 1;
			$this->current = $this->pos === $this->getPos();
			
			
			$p++;
			return true;
		}
		$p = 0;
		return false;
	}
	
	
	/**
	 * set mysql ressource as datasource
	 * specific for mysql
	 * @param	ressource	$res
	 * @param	int			$nbRows		rows per page
	 */
	public function setRessource($res, $nbRows) {
		global $babDB;
		$this->res = $res;
		$this->setMultiPage($babDB->db_num_rows($res), $nbRows);
		$this->setPos($this->getPos());
	}
		
	/**
	 * set pos into ressource
	 * specific for mysql
	 */
	public function setPos($pos) {
		global $babDB;
		$n = $babDB->db_num_rows($this->res);
		if (0 < $n && $n > $pos) {
			$babDB->db_data_seek($this->res, $pos);
		}
	}
	
	
	/**
	 * Set php array as datasource
	 * specific for array
	 * @param	array		$arr
	 * @param	int			$nbRows		rows per page
	 */
	public function setArray($arr, $nbRows) {
		$this->setMultiPage(count($arr), $nbRows);
		$res = array_slice($arr, $this->getPos(), $nbRows);
		$this->res = $res;
	}
	
	
	/**
	 * @return	string
	 */
	public function getPosParam() {
		return 'pos-'.$this->getId();
	}
	
	
	
	/**
	 * 
	 * @return int
	 */
	public function getPos() {
		return (int) $this->rp($this->getPosParam(),0);
	}
	
	
	/**
	 * Request param
	 */
	public function rp($key, $defaultval = '') {
		return bab_rp($key,$defaultval);
	}
	
	
	
	/**
	 * @param	array	$arr	: array where values are keys defined in _POST or _GET
	 */
	protected function setRequestParams($arr) {
	
		foreach($arr as $key => $value) {
			if (!isset($_POST[$value]) && !isset($_GET[$value])) {
				unset($arr[$key]);
			}
		}
	
		$this->requestparams = $arr;
		$this->baseurl = bab_url::request_array($arr);
	}
	
	/**
	 * @param	string	[...]	: keys from _POST or _GET
	 */
	public function setBaseUrl() {
		$this->setRequestParams(func_get_args());
	}
	
	
	/**
	 * Add search criterion
	 * @param	string	$key
	 */
	public function addSearchCriterionField($key) {
		$this->criterions[$key] = $key;
	}
	
	/**
	 * Get the list of fields without the fields defined by addSearchCriterionField
	 * @return array
	 */
	public function getHiddenFields() {
		
		$arr = isset($_GET) && is_array($_GET) ? $_GET : array();
		if (isset($_POST) && is_array($_POST)) {
			$arr = array_merge($arr,$_POST);
		}

		// remove criterions
		if (isset($this->criterions)) {
			foreach($this->criterions as $key) {
				if (isset($arr[$key])) {
					unset($arr[$key]);
				}
			}
		}

		// remove non string
		foreach($arr as $key => $value) {
			if (is_array($value)) {
				unset($arr[$key]);
			}
		}
		
		reset($arr);
		return $arr;
	}
	
	
	
	
	
	/**
	 * @return string
	 */
	public function getHiddenFieldsHtml() {
		$string = '';
		$arr = $this->getHiddenFields();
		foreach($arr as $key => $value) {
			$string .= sprintf('<input type="hidden" name="%s" value="%s" />', $key, bab_toHtml($value))."\n";
		}
		
		return $string;
	}
	
	/**
	 * Set a column name to display the column content associated to the page number
	 */
	public function displayFirstRowWithPageNumber($colname) {
		$this->pageinfo = $colname;
	}
	
	/**
	 * @access private
	 */
	public function generate_pagination_item($i) {
		$pos = ($i- 1) * $this->nbRows;
		$page_url = bab_url::mod($this->baseurl, $this->page_param, $pos);
		
		
		if (false !== $this->pageinfo) {
			
			$this->setPos($pos);
			$row = $this->getNextRow();
			$title = sprintf(' title="%s"',$row[$this->pageinfo]);
			
		} else {
		
			$title = '';
		}
		
		return ( $pos == $this->getPos()) ? '<strong class="ui-active-state">' . $i . '</strong>' : '<a class="ui-default-state" href="' . bab_toHtml($page_url) . '"'.$title.'>' . $i . '</a>';
	}
	
	
	
	/**
	 * PhpBB-ish pagination function
	 */
	public function generate_pagination($page_param, $previous_label, $next_label)
	{
		$this->page_param = $page_param;
		
		if ( 1 == $this->nbPages || 0 == $this->nbRows ) {
			return '';
		}
		
		$oldpos = $this->getPos();
	
		// page en cours
		$on_page = floor($this->getPos() / $this->nbRows) + 1;

	
		$page_string = '';
		if ( $this->nbPages > 10 ) {
		
			$begin_nb_pages		= 3;		// nombre de pages dans le bloc de debut
			$middle_limit 		= 5;		// numero de la page en cours maximum avant que le bloc du milieu ne soit cree
			$middle_nb_pages 	= 3;		// nombre de pages dans le bloc du milieu
			$end_nb_pages		= 3;		// nombre de pages dans le bloc de fin
	
			// begin
			
			for($i = 1; $i < $begin_nb_pages + 1; $i++) {
				$page_string .= $this->generate_pagination_item($i);
				if ( $i <  $begin_nb_pages ) {
					$page_string .= ", ";
				}
			}
	
			// middle
		
			if ( $on_page > 1  && $on_page < $this->nbPages ) {
				$page_string .= ( $on_page > $middle_limit ) ? ' ... ' : ', ';

				$middle_page_min = ( $on_page > ($middle_limit -1) ) ? $on_page : $middle_limit;
				$middle_page_max = ( $on_page < ($this->nbPages - $end_nb_pages -1) ) ? $on_page : ($this->nbPages - $end_nb_pages -1);

				for($i = $middle_page_min - 1; $i < ($middle_page_max + $middle_nb_pages -1); $i++) {
					$page_string .= $this->generate_pagination_item($i);
					if ( $i <  $middle_page_max + $middle_nb_pages -2 ) {
						$page_string .= ', ';
					}
				}

				$page_string .= ($on_page < ($this->nbPages - $end_nb_pages -1) ) ? ' ... ' : ', ';
			}
			else
			{
				$page_string .= ' ... ';
			}
			
			// end

			for($i = ($this->nbPages - $end_nb_pages +1); $i < ($this->nbPages + 1); $i++) {
				$page_string .= $this->generate_pagination_item($i);
				if( $i <  $this->nbPages ) {
					$page_string .= ', ';
				}
			}
			
		}
		else {
			for($i = 1; $i < $this->nbPages + 1; $i++) {
				$page_string .= $this->generate_pagination_item($i);
				if ( $i <  $this->nbPages ) {
					$page_string .= ', ';
				}
			}
		}
	

		if ( $on_page > 1 ) {
			$pos = ($on_page - 2) * $this->nbRows;
			$page_url = bab_url::mod($this->baseurl, $page_param, $pos);
			$page_string = '<a  class="ui-default-state" href="' . bab_toHtml($page_url) . '">'.bab_toHtml($previous_label).'</a>&nbsp;&nbsp;' . $page_string;
		}

		if ( $on_page < $this->nbPages ) {
			$pos = ($on_page) * $this->nbRows;
			$page_url = bab_url::mod($this->baseurl, $page_param, $pos);
			$page_string .= '&nbsp;&nbsp;<a class="ui-default-state" href="' . bab_toHtml($page_url) . '">'.bab_toHtml($next_label).'</a>';
		}

		if (false !== $this->pageinfo) {
			$this->setPos($oldpos);
		}
		
		return $page_string;
	}
	
	
	
	
	
	
	
	public function build_histogram($current_value, $max_value) {
	
		if ($max_value <= 0) {
			return bab_toHtml($current_value);
		}

		$length = ($current_value * $this->histogram_max_length) / $max_value;
		$length = round($length);
		$length++;
		
		$margin = $this->histogram_max_length - $length;
		
		return '<div class="histogram">'.bab_toHtml($current_value).'<img src="'.$GLOBALS['babSkinPath'].'images/Puces/Space1PxTrans.gif" style="width:'.$length.'px;margin-right:'.$margin.'px" align="absmiddle" /></div>';
		
	}
	
	
	
	
	
	
	public function orderUrl($value) {
		$url = bab_url::mod($this->baseurl, 'orderby', $value);
		$order_type = $this->rp('order_type','ASC');
		if ($value === $this->rp('orderby')) {
			$order_type = 'ASC' === $order_type ? 'DESC' : 'ASC';
			$url = bab_url::mod($this->baseurl, 'order_type', $order_type);
		}
		return $url;
	}
	
	public function getOrderType($default = 'ASC') {
		$order_type = $this->rp('order_type',$default);
		switch($order_type) {
			case 'ASC':
			case 'DESC':
				return $order_type;
				break;
				
			default:
				return 'ASC';
				break;
		}
	}
	
	
	public function getIconHtml($imageFilename, $alt) {
		return '<img src="'
		. bab_toHtml(bab_getAddonInfosInstance('widgets')->getImagesPath())
		. 'businessapplicationpage/'. bab_toHtml($imageFilename)
		. '" alt="'.bab_toHtml($alt)
		. '" />';
	}
	
	
	/**
	 * Edit link
	 * @param	string	$url
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function editLink($url, $alt = '') {
		return '<a href="'.bab_toHtml($url).'">'.$this->getIconHtml('page_edit.png', $alt).'</a>';
	}
	
	
	/**
	 * Add link
	 * @param	string	$url
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function addLink($url, $alt = '') {
		return '<a href="'.bab_toHtml($url).'">'.$this->getIconHtml('add.png', $alt).'</a>';
	}
	
	
	/**
	 * Accept link
	 * @param	string	$url
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function acceptLink($url, $alt = '') {
		return '<a href="'.bab_toHtml($url).'">'.$this->getIconHtml('accept.png', $alt).'</a>';
	}
	
	
	/**
	 * Create a link
	 * @param	string	$url
	 * @param	string	$label
	 * @return string	: html
	 */
	public function textLink($url, $label) {
		return '<a href="'.bab_toHtml($url).'">'.bab_toHtml($label).'</a>';
	}
	
	/**
	 * @param	string	$url
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function accessLink($url, $alt = '') {
		return '<a href="'.bab_toHtml($url).'">'.$this->getIconHtml('head.gif', $alt).'</a>';
	}	
	
	/**
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function noAccess($alt = '') {
		return $this->getIconHtml('action_fail.gif', $alt);
	}
	
	/**
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function alarm($alt = '') {
		return $this->getIconHtml('alarm.gif', $alt);
	}
	
	/**
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function warning($alt = '') {
		return $this->getIconHtml('warning.png', $alt);
	}
	
	/**
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function isOk($alt = '') {
		return $this->getIconHtml('action_success.gif', $alt);
	}
	
	
	
	/**
	 * @param	string	$url
	 * @param	string	$alt
	 * @return string	: html
	 */
	public function goUp($url, $alt = '') {
		return '<a href="'.bab_toHtml($url).'">'.$this->getIconHtml('go-up.png', $alt).'</a>';
	}
	
	
	/**
	 * @param	string	$url
	 * @return string	: html
	 */
	public function goDown($url, $alt) {
		return '<a href="'.bab_toHtml($url).'">'.$this->getIconHtml('go-down', $alt).'</a>';
	}
	
	
	/**
	 * 
	 * @param	string	$text
	 * @return string	: html
	 */
	public function sublevel($text) {

		return '&nbsp; '.$this->getIconHtml('pointer_blue.gif', '').bab_toHtml($text);
	}
	
	
	
	/**
	 * @param	string	$name
	 * @param	string	$value
	 * @param	int		$length
	 * @param	string	$classname
	 * @return string	: html
	 */
	public function editField($name, $value, $length, $classname = '') {
	
		if (!empty($classname)) {
			$classname = 'class="'.bab_toHtml($classname).'"';
		}
		return '<input type="text" name="'.bab_toHtml($name).'" value="'.bab_toHtml($value).'"  size="'.bab_toHtml($length).'" '.$classname.' />';
	}
	
	
	
	
	
	
	
	
	
	
	/**
	 * @return string
	 */
	public function getHtml($canvas) {
	
		$this->canvas = $canvas;
		$this->page_select = $this->generate_pagination($this->getPosParam(), $this->previousLabel, $this->nextLabel);
		return bab_printTemplate($this, bab_getAddonInfosInstance('widgets')->getRelativePath().'businessapplicationlist.html');
	}
	
	
	/**
	 * Export the list with xls header
	 * @param	string	$filename
	 */
	public function getXls($filename) {

		$filename = str_replace('/','-',$filename);
		$filename = str_replace('\\','-',$filename);
	
		header('Content-type: application/vnd.ms-excel');
		header("Content-Disposition: attachment; filename=\"".$filename.".xls\"");
		die($this->getHtml());
	}
	
	
	
	
	
	
	
	/**
	 * Create a list from a sql query
	 * @param	ressource	$res
	 * @param	array		$tablenames	
	 *
	 * @return Widget_BusinessApplicationList | null
	 */
	public function sqlHelper($res, $tablenames) {
		
		global $babDB;
		
		if (0 === $babDB->db_num_rows($res)) {
			return null;
		}
		
		$babDB->db_data_seek($res, 0);
		$firstrow = $babDB->db_fetch_assoc($res);
		$babDB->db_data_seek($res, 0);
		
		$columns = array_combine(array_keys($firstrow), array_keys($firstrow));
		
		// describe used tables
		
		foreach($tablenames as $tablename) {
			$infores = $babDB->db_query('
				SELECT COLUMN_NAME, COLUMN_COMMENT 
  				FROM INFORMATION_SCHEMA.COLUMNS 
 				WHERE table_name = '.$babDB->quote($tablename).' 
				AND table_schema = '.$babDB->quote($GLOBALS['babDBName']).' 
			');
			
			while ($arr = $babDB->db_fetch_assoc($infores)) {

				if (!empty($arr['COLUMN_COMMENT'])) {
					$columns[$arr['COLUMN_NAME']] = $arr['COLUMN_COMMENT'];
				}
			}
		}
		
		

		$this->setRessource($res, 20);
	
		foreach($columns as $key => $value) {
			$this->addColumn($key, $value, '', $this->orderUrl($key));
		}
		
		return $this;
	}
}
	
	
